<template>
  <view :class="{ Drawer: true, DrawerShow: visible }">
    <view
      class="Body"
      :style="{
        top: bodyStyle.top,
        bottom: bodyStyle.bottom,
        left: bodyStyle.left,
        right: bodyStyle.right,
        transform: bodyStyle.transform,
        transition: bodyStyle.transition,
      }"
    >
      <slot />
    </view>
  </view>
</template>
<script lang="ts">
import DrawerDirection from '@/components/DrawerDirection';
import Vue from '@/utils/Vue';
import { PropType } from 'vue';

interface IData {
  bodyStyle: Partial<CSSStyleDeclaration>;
}

export default Vue.extend({
  data(): IData {
    return {
      bodyStyle: {},
    };
  },
  components: {},
  options: { virtualHost: false },
  props: {
    visible: Boolean,
    direction: {
      type: Number as PropType<DrawerDirection>,
      default: DrawerDirection.bottom,
    },
  },

  beforeMount() {
    this.bodyStyle = this.getBodyStyle({
      transition: 'none',
    });
  },

  watch: {
    visible() {
      this.updateBodyStyle();
    },
    direction() {
      this.updateBodyStyle();
    },
  },

  methods: {
    getBodyStyle(
      value?: Partial<CSSStyleDeclaration>
    ): Partial<CSSStyleDeclaration> {
      const { direction, visible } = this;
      const result: Partial<CSSStyleDeclaration> = {
        top: '0px',
        bottom: '0px',
        left: '0px',
        right: '0px',
        transform: 'none',
        transition: `all 0.3s`,
        ...value,
      };
      switch (direction) {
        case DrawerDirection.top:
          result.bottom = 'unset';
          if (!visible) {
            result.transform = `translate(0, -100%)`;
          }
          break;
        case DrawerDirection.bottom: {
          result.top = 'unset';
          if (!visible) {
            result.transform = `translate(0, 100%)`;
          }
          break;
        }
        case DrawerDirection.left: {
          result.right = 'unset';
          if (!visible) {
            result.transform = `translate(-100%, 0)`;
          }
          break;
        }
        case DrawerDirection.right: {
          result.left = 'unset';
          if (!visible) {
            result.transform = `translate(100%, 0)`;
          }
          break;
        }
      }
      return result;
    },

    updateBodyStyle() {
      const value = this.getBodyStyle();
      this.bodyStyle = value;
    },
  },
});
</script>
<style lang="less" scoped>
.Drawer {
  position: fixed;
  background: transparent;
  pointer-events: none;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  transition: all 0.3s;

  .Body {
    position: absolute;
    transform: translate(0, 100%);
  }

  &.DrawerShow {
    pointer-events: all;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(6px);
  }
}
</style>
